package com.yilin.tms.gps.service.impl;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.yilin.commons.exception.BusinessException;
import com.yilin.commons.util.DateTimeUtil;
import com.yilin.commons.util.GpsMapUtil;
import com.yilin.commons.util.JsonUtil;
import com.yilin.tms.core.commons.zysdk.DataExchangeService;
import com.yilin.tms.core.entity.gps.Location;
import com.yilin.tms.core.entity.zhiyun.ZyResData;
import com.yilin.tms.gps.service.IGpsBeidouService;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @author liuxu :)
 * @version 1.0
 * @date 2023-7-13
 */
@Service
@Transactional
public class GpsBeidouService implements IGpsBeidouService {

   Logger log = LoggerFactory.getLogger(GpsBeidouService.class);
    DataExchangeService des;
    //配置
    private String zyUrl = "https://zhiyunopenapi.95155.com/save/apis/";//测试
    private String user = "65c53273-12f9-459b-a50c-7d1728e831ad";//
    private String pwd = "S7vJ3ziz1M7O25QA862814Eu21e42n";
    private String cid = "79b3822b-af43-448f-a073-c8960f3a250b"; //客户端id
    private String srt = "9a5ee6e8-ee6f-4dd0-bd17-fe4114f1c055"; //私钥
    private int reqCount = 0;

    /**
     * 根据北斗定位时间查询线路
     * 【轨迹·付费】
     */
    @Override
    public List<Location> getGpsDataWithTruckNoWithTime(String vehicleNo, Date startTime, Date endTime, String vco) {
        //从北斗获取轨迹
        List<Location> locationList = new ArrayList<>();
        //分段查询 每次均单独计算费用
        ArrayList<Map<String, Object>> myTraceListMap = new ArrayList<>();
        Map<String, String> map = new HashMap<>();
        map.put("vclN", vehicleNo);
        map.put("vco", vco);
        map.put("qryBtm", DateTimeUtil.dateToString(startTime, null));
        map.put("qryEtm", DateTimeUtil.dateToString(endTime, null));
        ZyResData<Map<String, String>> zyResData = zyPost(map, "routerPath");
        if (zyResData.getResult() == null) return null;
        if (zyResData.getStatus() != 1001) return null;
        //智运查询-北斗结果
        Gson gson = new Gson();
        String json = gson.toJson(zyResData.getResult().get("trackArray"));
        List<Map<String, Object>> maps = JsonUtil.jsonToObject(json, new TypeToken<List<Map<String, Object>>>() {
        });
        myTraceListMap.addAll(maps);
        if (myTraceListMap.size() > 0) {
            for (int i = 0; i < myTraceListMap.size(); i++) {
                if (myTraceListMap.get(i).get("lat") == null || (myTraceListMap.get(i).get("lat")).equals("null"))
                    continue;
                Location location = new Location();
                location.setmBearing(Float.parseFloat((String) myTraceListMap.get(i).get("agl")));
                double[] bdMap = GpsMapUtil.bdEncrypt(Double.parseDouble((String) myTraceListMap.get(i).get("lat")) / 600000.0, Double.parseDouble((String) myTraceListMap.get(i).get("lon")) / 600000.0);
                location.setmLatitude(bdMap[1]);
                location.setmLongitude(bdMap[0]);
                location.setmSpeed(Float.parseFloat((String) myTraceListMap.get(i).get("spd")) / 10.0F);// 10
                location.setmTime(DateTimeUtil.stringToDate((String) myTraceListMap.get(i).get("gtm"), "yyyyMMdd/HHmmss"));
                location.setStopTimeTip("0");
                locationList.add(location);
            }
            return locationList.stream().filter(distinctByKey(Location::getmLongitude)).collect(Collectors.toList());
        }
        return null;
    }

    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
    @Override
    public ZyResData zyPost(Map<String, String> parameters, String interfaceStr) {
        ZyResData zyResData = null;
        parameters.put("cid", cid);
        parameters.put("srt", srt);
        try {
            String res = getDataExchangeService().postHttps(zyUrl + interfaceStr, parameters);
            zyResData = JsonUtil.jsonToObject(res, new TypeToken<ZyResData>() {
            });

        } catch (Exception e) {
            log.info("业务请求异常，异常：" + e.getMessage());
        }
        if (zyResData == null) {
            throw new BusinessException("请求失败，请稍后重试！");
        }
        if (zyResData.getStatus() == 1006) {//无结果
            if (reqCount > 5) throw new BusinessException("请求服务器无结果达到5次，请联系智运平台");
            reqCount++;
            return zyPost(parameters, interfaceStr);
        }
        reqCount = 0;
        return zyResData;
    }

    public DataExchangeService getDataExchangeService() {
        try {
            if (des == null) {
                des = new DataExchangeService(20000, 25000);
            }
        } catch (Exception e) {
            log.info("智运平台接口服务异常，异常：" + e.getMessage());
        }
        return des;
    }
}
